import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 汉字用零一二三四五六七八九作为基本计数，与阿拉伯数字靠数字偏移位置的权位不一样。
 * 中文数字是才有“数字+权位”的方式组成数字，比方百，千，万。
 * <p>
 * 中文数字每一个数字后都会跟上一个权位。
 * 权位就是数字的量值，相当于阿拉伯数字的数位。
 * <p>
 * 中文计数以万为小节，万下面没有节权，万之上是亿为节权。
 * <p>
 * 中文另一个特点是多变的“零”，大概总结为三个规则：
 * <p>
 * 1.以10000为小节。小节的结尾即使是0，也不使用“零”。
 * <p>
 * 2.小节内两个非0数字之间要使用“零”。
 * <p>
 * 3.当小节的“千”位是0时，若本小节的前一小节无其它数字。
 * 则不用“零”，否则就要用“零”。
 */
public class ChinaConvertNumber {
    private static long result = 0;
    //HashMap Key Value 映射
    private static Map<String, Long> unitMap = new HashMap<String, Long>();
    private static Map<String, Long> numMap = new HashMap<String, Long>();
    //String split
    private static String stryi = new String();
    private static String stryiwan = new String();
    private static String stryione = new String();
    private static String strwan = new String();
    private static String strone = new String();

    public static void Mapping(String chnStr) {
        /**
         *  单位 最后的L代表指定类型 L=Long
         *  不加L默认是int，int转为long是安全的，所以会自动转，能编译通过
         * 实际上内存中Long只是一个long类型的变量，它存在于向stack（栈）中，
         * 数值并不在其中存放，它指向heap（堆）中另一块真正存放数值的内存，
         * 加L的目的就是为了让heap中也创建一块long类型所需要的内存，用来来放数值。
         * 所以说=前后两者其实是在不同的两块内存，只不过有个无形的指针将两者连接起来了
         */
        unitMap.put("十", 10L);
        unitMap.put("百", 100L);
        unitMap.put("千", 1000L);
        unitMap.put("万", 10000L);
        unitMap.put("亿", 100000000L);
        //num 基本数据类型
        numMap.put("零", 0L);
        numMap.put("一", 1L);
        numMap.put("二", 2L);
        numMap.put("三", 3L);
        numMap.put("四", 4L);
        numMap.put("五", 5L);
        numMap.put("六", 6L);
        numMap.put("七", 7L);
        numMap.put("八", 8L);
        numMap.put("九", 9L);
        //Remove 0;
        for (int i = 0; i < chnStr.length(); i++) {
            if ('零' == (chnStr.charAt(i))) { //Found 0 return char
                chnStr = chnStr.substring(0, i) + chnStr.substring(i + 1);
            }
        }
        //Split into three parts
        int index = 0;//basic data
        boolean yiflag = true;
        boolean yiwanflag = true; //节权 万之上是亿为节权。亿字节中存在万
        boolean wanflag = true;//小节  以“万”为小节，对应一个节权位万以下没有节权位每个小节内部以“十百千”为权位独立计数
        for (int i = 0; i < chnStr.length(); i++) {
            if ('亿' == (chnStr.charAt(i))) {
                //存在亿之前还有小节的情况
                stryi = chnStr.substring(0, i);
                if (chnStr.indexOf('亿' + "") > chnStr.indexOf('万' + "")) {
                    stryi = chnStr.substring(0, i);
                    for (int j = 0; j < stryi.length(); j++) {
                        if ('万' == (stryi.charAt(j))) {
                            yiwanflag = false;
                            strwan = stryi.substring(0, j);
                            strone = stryi.substring(j + 1);

                        }
                    }
                }
                if (yiwanflag) {//亿字节中没有万，直接赋值
                    stryione = stryi;
                }
                index = i + 1;
                yiflag = false;// Sectioning Completed
                strone = chnStr.substring(i + 1);
            }
            if ('万' == chnStr.charAt(i) && chnStr.indexOf('亿' + "") < chnStr.indexOf('万' + "")) {
                strwan = chnStr.substring(index, i);
                strone = chnStr.substring(i + 1);
                wanflag = false;//Sectioning Completed
            }
        }
        if (yiflag && wanflag) { //Not Processed
            strone = chnStr;
        }
    }

    //   Convert a String To a Number 字符串转换为数字
    public static long Conversion(String str) {
        long strreuslt = 0;
        long value1 = 0;
        long value2 = 0;
        long value3 = 0;
        if (str.isEmpty()) {
            return 0;
        }
        for (int i = 0; i < str.length(); i++) {
            char bit = str.charAt(i);
            //Number
            if (numMap.containsKey(bit + "")) {
                value1 = numMap.get(bit + "");
                if (i == str.length() - 1) {
                    strreuslt += value1;
                }
            }
            //单位
            else if (unitMap.containsKey(bit + "")) {
                value2 = unitMap.get(bit + "");
                if (value1 == 0 && value2 == 10L) {
                    value3 = 1 * value2;
                } else {
                    value3 = value1 * value2;
                    //Clear To Avoid Repeated Reading 清零 避免重复读取
                    value1 = 0;
                }
                strreuslt += value3;
            }
        }
        return strreuslt;
    }

    //
    public static long Combined(String chnStr) {
        Mapping(chnStr);
        long stryiwanresult = Conversion(stryiwan);
        long stryioneresult = Conversion(stryione);
        long strwanresult = Conversion(strwan);
        long stroneresult = Conversion(strone);
        result = (stryiwanresult * 10000 + stryioneresult) * 100000000 + strwanresult * 10000 + stroneresult;
        //Reset
        stryi = "";
        strwan = "";
        strone = "";
        return result;
    }

    public static void main(String[] args) {
        List<String> chnList = new java.util.ArrayList<String>();
        chnList.add("一");
        chnList.add("一十五");
        chnList.add("十五");
        chnList.add("二十");
        chnList.add("二十三");
        chnList.add("一百");
        chnList.add("一百零一");
        chnList.add("一百一十");
        chnList.add("一百一十一");
        chnList.add("一千");
        chnList.add("一千零一");
        chnList.add("一千零三十一");
        chnList.add("一万零一");
        chnList.add("一万零二十一");
        chnList.add("一万零三百二十一");
        chnList.add("一万一千三百二十一");
        chnList.add("三千零十五万");
        chnList.add("三千零一十五万");
        chnList.add("三千五百六十八万零一百零一");
        chnList.add("五十亿三千零七十五万零六百二十二");
        chnList.add("十三亿三千零十五万零三百一十二");
        chnList.add("三千零七十八亿三千零十五万零三百一十二");
        chnList.add("一千二百五十八亿");
        chnList.add("一千二百五十八万亿零三千三百二十一");

        for (String chnStr : chnList) {
            System.out.println(chnStr);
            System.out.println(Combined(chnStr));
        }
    }
}
